﻿using System;
using System.Drawing;
using Dataweb.NShape.Advanced;
using Dataweb.NShape;
using System.IO;

namespace cz.zcu.PreSti.Shapes
{
    public abstract class StimulusSymbol : RectangleBase, ISymbol
    {

        protected override void InitializeToDefault(IStyleSet styleSet)
        {
            base.InitializeToDefault(styleSet);
            Height = 69;
            Width = 92;
        }

        protected override int ControlPointCount
        {
            get { return ActionsCount + EventsCount + SettersCount + GettersCount; }
        }


        public override bool HasControlPointCapability(ControlPointId controlPointId, ControlPointCapabilities controlPointCapability)
        {
            /*if (controlPointId == 0)
                return false;//((controlPointCapability & ControlPointCapabilities.Resize) != 0);
            else */
            if (controlPointId > 0 && controlPointId < ActionsCount + EventsCount + SettersCount + GettersCount + 1)
                return ((controlPointCapability & ControlPointCapabilities.Connect) != 0);
            else return base.HasControlPointCapability(controlPointId, controlPointCapability);
        }


        protected internal StimulusSymbol(ShapeType shapeType, Template template)
            : base(shapeType, template)
        {
        }

        protected internal StimulusSymbol(ShapeType shapeType, IStyleSet styleSet)
			: base(shapeType, styleSet) {
		}


        protected override void CalcControlPoints()
        {

            int left = (int)Math.Round(-Width / 2f);
            int top = (int)Math.Round(-Height / 2f);
            int right = left + Width;
            int bottom = top + Height;

            ControlPoints[0].X = left;
            ControlPoints[0].Y = top + Height / 2;
            ControlPoints[2].X = right;
            ControlPoints[2].Y = top + Height / 2;
            ControlPoints[1].X = left;
            ControlPoints[1].Y = 4 * connectorWidth;

            for (int i = 0; i < SettersCount; i++)
            {
                int w = Width / SettersCount;
                ControlPoints[i + ActionsCount + EventsCount].X = left + i * w + w / 2;
                ControlPoints[i + ActionsCount + EventsCount].Y = top;
            }

            for (int i = 0; i < GettersCount; i++)
            {
                int w = Width / GettersCount;
                ControlPoints[i + ActionsCount + EventsCount + SettersCount].X = left + i * w + w / 2;
                ControlPoints[i + ActionsCount + EventsCount + SettersCount].Y = bottom;
            }
        }


        protected override void CalcCaptionBounds(int index, out Rectangle captionBounds)
        {
            if (index != 0) throw new IndexOutOfRangeException();
            int left = (int)Math.Round(-Width / 2f);
            int top = (int)Math.Round(-Height / 2f);
            captionBounds = Rectangle.Empty;
            captionBounds.X = left;
            captionBounds.Y = top;
            captionBounds.Width = Width;
            captionBounds.Height = Height;
        }


        protected override bool CalculatePath()
        {
            if (base.CalculatePath())
            {
                int left = (int)Math.Round(-Width / 2f);
                int top = (int)Math.Round(-Height / 2f);
                int right = left + Width;
                int bottom = top + Height;

                Rectangle shapeRect = new Rectangle(left, top, Width, Height);

                Path.Reset();
                Path.StartFigure();
                Path.AddRectangle(shapeRect);
                PointF[] a = { new PointF((float)right, top + Height / 2f - connectorWidth), new PointF((float)right - connectorWidth, top + Height / 2f), new PointF(right, top + Height / 2f + connectorWidth) };
                PointF[] b = { new PointF(left, top + Height / 2f - connectorWidth), new PointF(left + connectorWidth, top + Height / 2f), new PointF(left, top + Height / 2f + connectorWidth) };
                PointF[] c = { new PointF(left, 3 * connectorWidth), new PointF(left + connectorWidth, 4 * connectorWidth), new PointF(left, 5 * connectorWidth) };
                Path.StartFigure();
                Path.FillMode = System.Drawing.Drawing2D.FillMode.Winding;
                Path.AddPolygon(a);
                Path.StartFigure();
                Path.AddPolygon(b);
                Path.StartFigure();
                Path.AddPolygon(c);

                Path.StartFigure();
                for (int i = 0; i < SettersCount; i++)
                {
                    int w = Width / SettersCount;
                    int posX = left + i * w + w / 2;
                    Path.AddCurve(new PointF[] { new PointF(posX - 4, top), new PointF(posX, top + 4), new PointF(posX + 4, top) }, 1);
                }

                Path.StartFigure();
                for (int i = 0; i < GettersCount; i++)
                {
                    int w = Width / GettersCount;
                    int posX = left + i * w + w / 2;
                    Path.AddCurve(new PointF[] { new PointF(posX - 4, bottom), new PointF(posX, bottom - 4), new PointF(posX + 4, bottom) }, 1);
                }
                Path.CloseFigure();
                return true;
            }
            return false;
        }


        #region Fields
        private int connectorWidth = 5;
        #endregion


        #region ISymbol Members

        public abstract BaseComponent initializeComponent(IPresentation p);

        public virtual int ActionsCount
        {
            get { return 2; }
        }

        public virtual int EventsCount
        {
            get { return 1; }
        }

        public virtual int SettersCount
        {
            get { return 0; }
        }

        public virtual int GettersCount
        {
            get { return 0; }
        }

        public virtual string GetTitleForAction(int id)
        {
            switch (id)
            {
                case 0:
                    return "Start the stimuli";
                case 1:
                    return "Terminate the stimuli";
            }
            return null;
        }

        public virtual string GetTitleForEvent(int id)
        {
            switch (id)
            {
                case 0:
                    return "End of the stimuli";
            }
            return null;
        }

        public virtual string GetTitleForSetter(int id)
        {
            return null;
        }

        public virtual string GetTitleForGetter(int id)
        {
            return null;
        }

        #endregion
    }
}
